<?php



/**
 * 微信授权帮助类
 * @copyright     殷言力
 * @package       weixin
 */
class VisitorComponent{

	public $name = 'Visitor';
	// 调用外部控制器
	protected $_controller = NULL;

	private $app_id = NULL;

	private $app_secret = NULL;

	public $error_msg = '';

	public function __construct(ComponentCollection $collection, $settings = array()){
		parent::__construct($collection, $settings);

		$this->_controller = $collection->getController();
		$this->request = $this->_controller->request;
		$this->Session = $this->_controller->Session;
	}

	/**
	* 初始化公众号资料，从数据库中获取公众号APPID，APPSECRET
	*/
	public function init(){
		$this->_controller->loadModel('WeixinAccess');
		if($access_row = $this->_controller->WeixinAccess->find('first')){
			if (isset($access_row['WeixinAccess']['app_id']) && isset($access_row['WeixinAccess']['app_secret'])) {
				$this->app_id = $access_row['WeixinAccess']['app_id'];
				$this->app_secret = $access_row['WeixinAccess']['app_secret'];
				$this->error_msg.= '公众号初始化成功;appid:'.$this->app_id;
				return true;
			}else{
				$this->error_msg.= '公众号设置出错';
				return false;
			}
		}else{
			$this->error_msg.= '未查询到公众号设置';
			return false;
		}
	}

	/**
	* 通过oauth2授权入口，获取open_id，并处理信息
	* @param $easy_mode 是否需要授权获取用户信息（true：否，false:是）
	* @return $open_id
	*/
	public function get_opid($easy_mode=true){
		/*debugmode*/
		if ($this->request->query('debug_mode') == 1) { // 测试模式
			$open_id = 'testtesttesttesttesttest1235';
			$_SESSION['open_id'] = $open_id;
			$this->error_msg.= "\n测试模式;open_id:".$open_id;
			return $open_id;
		}
		// elseif ($this->request->query('debug_mode') == 2) { // 测试模式
		// 	unset($_SESSION['open_id']);
		// 	exit;
		// }

		/*正式接口*/
		// 如果已经授权过，返回session中的open_id
		if (isset($_SESSION['open_id'])) {
			$this->error_msg.= "\nsession;open_id:".$_SESSION['open_id'];
			return $_SESSION['open_id'];
		}
		$opid = $this->get_visitor($easy_mode);
		$this->logger("return_open_id:$opid");
		if ($opid && strlen($opid) == 28) {
			$this->logger("open_id:$opid");
			$_SESSION['open_id'] = $opid;
			$this->error_msg.= "\n基本授权获取;open_id:".$opid;
			return $opid;
		}elseif(is_array($opid)){
			if (!$easy_mode) {
				$openid 	= $opid['openid'];
				$nickname	= @$opid['nickname'];
				$sex		= @$opid['sex'];
				$province	= @$opid['province'];
				$city		= @$opid['city'];
				$country	= @$opid['country'];
				$headimgurl	= @$opid['headimgurl'];
				$privilege	= @$opid['privilege'];
				$privilege	= json_encode($privilege,JSON_UNESCAPED_UNICODE);
				
				if ($row['nickname'] != $nickname) {
					$data_arr = compact('openid','nickname','sex','city','province','country','headimgurl','privilege');
					$data_arr = $data_arr?$data_arr:'';
					$this->loadModel('WeixinVisitor');
					$visitor_id = $this->WeixinVisitor->save($data_arr);
				}
				$this->error_msg.= "\n授权获取用户信息;open_id:".$opid;
				return $openid;
			}
		}else{
			$this->error_msg.= "\n授权失败;open_id:".$opid;
			return $opid;
		}
	}

	/**
	* 内部接口，判断session中是否存在，对应不同模式请求不同接口流程
	* @param $easy_mode 是否需要授权获取用户信息（true：否，false:是）
	* @return $open_id
	*/
	private function get_visitor($easy_mode=true){
		if ($easy_mode && isset($_SESSION['open_id'])) {
			$this->error_msg.= "\n授权session;open_id:".$_SESSION['open_id'];
			return $_SESSION['open_id'];
		}else{
			if (isset($_GET['code'])) {
				$this->error_msg.= "\n授权code;code:".$_GET['code'];
				return $this->getUserInfo($easy_mode);
			}
			if ($easy_mode) {
				$this->goToUrl();
			}else{
				$mode = 'snsapi_userinfo';
				$this->goToUrl('userinfo',$mode);
			}
		}
	}

	/**
	* easy_mode = true 简单模式，获取openid
	*/
	private function goToUrl($state='STATE',$scope='snsapi_base'){
		//snsapi_userinfo , snsapi_base
		$script='http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
		$url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->app_id.'&redirect_uri='.urlencode($script).'&response_type=code&scope='.$scope.'&state='.$state.'#wechat_redirect';
		$this->error_msg.= "\n跳转授权;url:".$url;
		// header("Location:".$url);
		$this->_controller->redirect($url);
	}

	/**
	* easy_mode = false 非简单模式,获取用户详细信息
	*/
	private function getUserInfo($easy_mode=true){
		if(isset($_GET['code'])){
			$code = $_GET['code'];
			$link = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->app_id.'&secret='.$this->app_secret.'&code='.$code.'&grant_type=authorization_code';
			$result = $this->startCurl($link,$easy_mode);
			if (isset($result['openid'])) {
				$_SESSION['open_id'] 	= $result['openid'];
				$_SESSION['nickname'] 	= @$result['nickname'];
				$_SESSION['sex'] 		= @$result['sex'];
				$_SESSION['language'] 	= @$result['language'];
				$_SESSION['city'] 		= @$result['city'];
				$_SESSION['province'] 	= @$result['province'];
				$_SESSION['country'] 	= @$result['country'];
				$_SESSION['headimgurl'] = @$result['headimgurl'];
				$_SESSION['privilege'] 	= @$result['privilege'];
				$this->openid = $result['openid'];
				return $result;
			}else{
				return $result;
			}
		}
		return false;
	}

	/**
	* 内部功能，获取用户详细信息请求
	*/
	private function startCurl($link,$easy_mode){
		
		//初始化一个会话
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $link);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($ch);
		curl_close($ch);
		
		$array = json_decode($output, true);
		
		if($easy_mode){
			$this->logger("array:".var_export($array,true));
			return $array['openid'];
		}
		
		$access_token 	= $array["access_token"];
		$expires_in		= $array["expires_in"];
		$refresh_token	= $array["refresh_token"];
		$openid			= $array["openid"];
		$scope			= $array["scope"];
		
		
		$link = "https://api.weixin.qq.com/sns/userinfo?access_token=".$access_token."&openid=".$openid.'&lang=zh_CN';
		//初始化一个会话
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $link);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		//https请求
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		$output = curl_exec($ch);
		curl_close($ch);
		
		$array = json_decode($output, true);
		
		/* ["openid"]=> string(28)
		 * ["nickname"]=> string(9)
		 * ["sex"]=> int(1) 
		 * ["language"]=> string(5)
		 * ["city"]=> string(6)
		 * ["province"]=> string(6)
		 * ["country"]=> string(6)
		 * ["headimgurl"]=> string(121)
		 * ["privilege"]=> array(0)
		*/
		return $array;
	}

	/**
	* 测试用内部方法
	*/
	private function logger($msg){
		file_put_contents('api_log.txt', $msg."\n",FILE_APPEND);
	}
}